﻿/**************************************************************
 *
 * 唯一标识：ab23e4f8-e429-40a4-bd9a-764c232c53ce
 * 命名空间：MediatR.Behaviors
 * 创建时间：2023/8/18 9:34:10
 * 机器名称：DESKTOP-S0D075D
 * 创建者：antho
 * 电子邮箱：fengqinhua2016@163.com
 * 描述：
 *
 **************************************************************/

//using MediatR;
//using Microsoft.EntityFrameworkCore;
//using Microsoft.Extensions.DependencyInjection;
//using Microsoft.Extensions.Logging;
//using Sgr.Domain.Uow;
//using Sgr.EntityFrameworkCore;
//using Sgr.Exceptions;
//using Sgr.Utilities;
//using System;
//using System.Collections.Generic;
//using System.Data;
//using System.Linq;
//using System.Net.Cache;
//using System.Runtime.CompilerServices;
//using System.Threading;
//using System.Threading.Tasks;

//namespace Sgr.MediatR.Behaviors
//{
//    /// <summary>
//    /// MediatR事务处理行为
//    /// 用于处理Command和Query的数据库事务
//    /// </summary>
//    /// <typeparam name="TRequest">请求类型</typeparam>
//    /// <typeparam name="TResponse">响应类型</typeparam>
//    public class TransactionBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse> where TRequest : IRequest<TResponse>
//    {
//        private readonly IUnitOfWorkManager _unitOfWorkManager;
//        private readonly ILogger<TransactionBehavior<TRequest, TResponse>> _logger;

//        //private readonly IIntegrationEventService _integrationEventService;

//        public TransactionBehavior(
//            IUnitOfWorkManager unitOfWorkManager,
//            //IIntegrationEventService integrationEventService,
//            ILogger<TransactionBehavior<TRequest, TResponse>> logger)
//        {
//            _unitOfWorkManager = unitOfWorkManager ?? throw new ArgumentNullException(nameof(unitOfWorkManager));
//            //_integrationEventService = integrationEventService ?? throw new ArgumentException(nameof(IIntegrationEventService));
//            _logger = logger ?? throw new BusinessException(nameof(ILogger));
//        }

//        public async Task<TResponse> Handle(TRequest request, RequestHandlerDelegate<TResponse> next, CancellationToken cancellationToken)
//        {
//            //如果已存在工作单元，则直接执行请求
//            if (_unitOfWorkManager.Current != null)
//            {
//                return await next();
//            }

//            using (var uow = _unitOfWorkManager.Begin(new UnitOfWorkOption()
//            {
//                IsTransactional = true,
//                IsolationLevel = IsolationLevel.ReadCommitted,
//                Timeout = 30000
//            }))
//            {
//                try
//                {
//                    var result = await next();

//                    await uow.CommitAsync();

//                    return result;
//                }
//                catch (Exception ex)
//                {
//                    await uow.RollbackAsync();
//                    _logger.LogError(ex, "工作单元执行失败，已回滚");
//                    throw;
//                }
//            }

//            //try
//            //{
//            //    // 解析该请求应该使用哪个工作单元
//            //    UnitOfWorkDbContext? dbContext = ResolveDbContext();

//            //    if (dbContext == null)
//            //    {
//            //        _logger.LogDebug("请求 {RequestName} 未指定工作单元，将直接执行", TypeHelper.GetGenericTypeName(typeof(TRequest)));
//            //        return await next();
//            //    }

//            //    // 如果已有活动事务，直接执行请求
//            //    if (dbContext.HasActiveTransaction)
//            //    {
//            //        _logger.LogDebug("检测到活动事务，请求 {RequestName} 将在现有事务中执行", TypeHelper.GetGenericTypeName(typeof(TRequest)));
//            //        return await next();
//            //    }

//            //    TResponse? response = default;

//            //    var strategy = dbContext.Database.CreateExecutionStrategy();

//            //    await strategy.ExecuteAsync(async () =>
//            //    {
//            //        //Guid transactionId;

//            //        await using var transaction = await dbContext.BeginTransactionAsync() ?? throw new BusinessException("TransactionBehavior : dbContext transaction is null");
//            //        try
//            //        {
//            //            using (_logger.BeginScope(new List<KeyValuePair<string, object>> { new("TransactionContext", transaction.TransactionId) }))
//            //            {
//            //                response = await next();

//            //                await dbContext.CommitTransactionAsync(transaction);

//            //                //transactionId = transaction.TransactionId;
//            //            }
//            //        }
//            //        catch (Exception ex)
//            //        {
//            //            _logger.LogWarning(ex, "回滚事务 {TransactionId} 用于请求 {RequestName}",
//            //                transaction.TransactionId, TypeHelper.GetGenericTypeName(typeof(TRequest)));
//            //            dbContext.RollbackTransaction();
//            //            throw;
//            //        }

//            //        //await _integrationEventService.PublishEventsThroughEventBusAsync(transactionId);
//            //    });

//            //    return response ?? throw new BusinessException("command response is null");
//            //}
//            //catch (Exception ex)
//            //{
//            //    _logger.LogError(ex, "Error Handling transaction for {CommandName} ({@Command})", TypeHelper.GetGenericTypeName(typeof(TRequest)), request);
//            //    throw;
//            //}
//        }

//        /// <summary>
//        /// 解析请求对应的DbContext
//        /// </summary>
//        private UnitOfWorkDbContext? ResolveDbContext()
//        {
//            Type requestType = typeof(TRequest); // 使用typeof代替GetType()

//            // 尝试从缓存获取
//            if (!_unitOfWorkTypeCache.TryGetValue(requestType, out Type? unitOfWorkType))
//            {
//                // 只在首次访问时执行反射
//                var unitOfWorkInterface = requestType.GetInterfaces()
//                    .FirstOrDefault(i => i.IsGenericType &&
//                                       i.GetGenericTypeDefinition() == typeof(IRequireUnitOfWork<>));

//                //// 检查是否为通知（领域事件）
//                //if (typeof(INotification).IsAssignableFrom(requestType))
//                //{
//                //    // 领域事件不应单独指定工作单元
//                //    // 而是使用触发它的Command的工作单元
//                //    return null;
//                //}

//                unitOfWorkType = unitOfWorkInterface?.GetGenericArguments()[0];
//                _unitOfWorkTypeCache.TryAdd(requestType, unitOfWorkType);
//            }

//            if (unitOfWorkType == null)
//                return null;

//            return _serviceProvider.GetService(unitOfWorkType) as UnitOfWorkDbContext
//                ?? throw new BusinessException($"工作单元类型 {unitOfWorkType.Name} 它不是 UnitOfWorkDbContext");

//            //// 从服务容器中获取对应的工作单元实现
//            //var unitOfWork = _serviceProvider.GetService(unitOfWorkType) as IUnitOfWork
//            //    ?? throw new BusinessException($"找不到类型为 {unitOfWorkType.Name} 的工作单元实现");

//            //return unitOfWork as UnitOfWorkDbContext
//            //    ?? throw new BusinessException($"工作单元类型 {unitOfWorkType.Name} 的实现不是 UnitOfWorkDbContext");

//            //// 通过命名空间判断，作为后备策略
//            //string? ns = requestType.Namespace;

//            //if (!string.IsNullOrEmpty(ns))
//            //{
//            //    if (ns.Contains(".UPMS."))
//            //    {
//            //        var upmsUnitOfWork = _serviceProvider.GetService<IUpmsUnitOfWork>();
//            //        if (upmsUnitOfWork is UnitOfWorkDbContext dbContext)
//            //            return dbContext;
//            //    }

//            //    // 添加其他模块的命名空间检测...
//            //}

//            //// 默认使用SgrDbContext
//            //var defaultUnitOfWork = _serviceProvider.GetService<ISgrUnitOfWork>();
//            //if (defaultUnitOfWork is UnitOfWorkDbContext dbContext)
//            //    return dbContext;

//            //throw new BusinessException("无法确定请求对应的工作单元");
//        }
//    }
//}